package com.hoo.util;


import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringEscapeUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Random;

/**
 * @类功能说明：编码通用类EncodeUtils,集成Commons-Codec,Commons-Lang及JDK提供的编解码方法.
 * @版本：V1.0
 */
public class EncodeUtils {

    private static final String DEFAULT_URL_ENCODING = "UTF-8";

    /**
     * 函数功能: Hex编码
     */
    public static String hexEncode(byte[] input) {
        return Hex.encodeHexString(input);
    }

    /**
     * 函数功能: Hex解码
     */
    public static byte[] hexDecode(String input) {
        try {
            return Hex.decodeHex(input.toCharArray());
        } catch (DecoderException e) {
            throw new IllegalStateException("Hex Decoder exception", e);
        }
    }

    /**
     * 函数功能: Base64编码
     */
    public static String base64Encode(byte[] input) {
        return new String(Base64.encodeBase64(input));
    }

    /**
     * 函数功能: Base64编码, URL安全(将Base64中的URL非法字符�?,/=转为其他字符, 见RFC3548)
     */
    public static String base64UrlSafeEncode(byte[] input) {
        return Base64.encodeBase64URLSafeString(input);
    }

    /**
     * 函数功能: Base64解码
     */
    public static byte[] base64Decode(String input) {
        return Base64.decodeBase64(input);
    }

    /**
     * 函数功能: URL 编码, Encode默认为UTF-8
     */
    public static String urlEncode(String input) {
        return urlEncode(input, DEFAULT_URL_ENCODING);
    }

    /**
     * 函数功能: URL 编码
     */
    public static String urlEncode(String input, String encoding) {
        try {
            return URLEncoder.encode(input, encoding);
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException("Unsupported Encoding Exception", e);
        }
    }

    /**
     * 函数功能: URL 解码, Encode默认为UTF-8
     */
    public static String urlDecode(String input) {
        return urlDecode(input, DEFAULT_URL_ENCODING);
    }

    /**
     * 函数功能: URL 解码
     */
    public static String urlDecode(String input, String encoding) {
        try {
            return URLDecoder.decode(input, encoding);
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException("Unsupported Encoding Exception", e);
        }
    }

    /**
     * 函数功能: Html 转码
     */
    public static String htmlEscape(String html) {
        return StringEscapeUtils.escapeHtml3(html);
    }

    /**
     * 函数功能: Html 解码
     */
    public static String htmlUnescape(String htmlEscaped) {
        return StringEscapeUtils.unescapeHtml3(htmlEscaped);
    }

    /**
     * 函数功能: Xml 转码
     */
    public static String xmlEscape(String xml) {
        return StringEscapeUtils.escapeXml(xml);
    }

    /**
     * 函数功能: Xml 解码
     */
    public static String xmlUnescape(String xmlEscaped) {
        return StringEscapeUtils.unescapeXml(xmlEscaped);
    }

    /**
     * 函数功能: MD5签名
     */
    public static String testDigest(String myinfo) {
        byte[] digesta = null;
        try {
            java.security.MessageDigest alga = java.security.MessageDigest.getInstance("MD5");
            alga.update(myinfo.getBytes("gbk"));
            digesta = alga.digest();
        } catch (UnsupportedEncodingException e) {
            System.out.println("-----------------------------------------------");
            System.out.println("MD5发生错误");
            System.out.println("-----------------------------------------------");
            return null;
        } catch (java.security.NoSuchAlgorithmException ex) {
            System.out.println("-----------------------------------------------");
            System.out.println("MD5发生错误");
            System.out.println("-----------------------------------------------");
            return null;
        }
        return byte2hex(digesta);
    }

    /**
     * 函数功能: MD5签名
     */
    public static String testDigest(String myinfo, String encode) throws UnsupportedEncodingException {
        byte[] digesta = null;
        try {
            java.security.MessageDigest alga = java.security.MessageDigest.getInstance("MD5");
            alga.update(myinfo.getBytes(encode));
            digesta = alga.digest();

        } catch (java.security.NoSuchAlgorithmException ex) {
            System.out.println("MD5发生错误");
            return null;
        }
        return byte2hex(digesta);
    }

    /**
     * 函数功能: 二进制转为十六进制串
     */
    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
            if (n < b.length - 1) {
                // hs = hs;
            }
        }
        return hs;
    }

    /**
     * 函数功能: 生成随即密码
     */
    public static String genRandomNum(int pwd_len) {
        // 35是因为数组是�?�?��的，26个字�?10个数�?
        final int maxNum = 10;
        int i; // 生成的随机数
        int count = 0; // 生成的密码的长度
        /*
         * char[] str = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
         * 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
         * 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
         */

        char[] str = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

        StringBuffer pwd = new StringBuffer("");
        Random r = new Random();
        r.setSeed(System.currentTimeMillis());
        while (count < pwd_len) {
            // 生成随机数，取绝对�?，防止生成负数，

            i = Math.abs(r.nextInt(maxNum)); // 生成的数�?���?6-1

            if (i >= 0 && i < str.length) {
                pwd.append(str[i]);
                count++;
            }
        }

        return pwd.toString();
    }

    //易宝特殊md5签名方式
    public static String hmacSign(String aValue, String aKey) {
        byte k_ipad[] = new byte[64];
        byte k_opad[] = new byte[64];
        byte keyb[];
        byte value[];
        try {
            keyb = aKey.getBytes("UTF-8");
            value = aValue.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            keyb = aKey.getBytes();
            value = aValue.getBytes();
        }

        Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
        Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
        for (int i = 0; i < keyb.length; i++) {
            k_ipad[i] = (byte) (keyb[i] ^ 0x36);
            k_opad[i] = (byte) (keyb[i] ^ 0x5c);
        }

        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {

            return null;
        }
        md.update(k_ipad);
        md.update(value);
        byte dg[] = md.digest();
        md.reset();
        md.update(k_opad);
        md.update(dg, 0, 16);
        dg = md.digest();
        return toHex(dg);
    }

    public static String toHex(byte input[]) {
        if (input == null)
            return null;
        StringBuffer output = new StringBuffer(input.length * 2);
        for (int i = 0; i < input.length; i++) {
            int current = input[i] & 0xff;
            if (current < 16)
                output.append("0");
            output.append(Integer.toString(current, 16));
        }

        return output.toString();
    }

    //以上即是易宝md5签名方式
    public static void main(String saf[]) {
        String usercodeString = "A672353";
        String pass = "ofcardpay";
        pass = testDigest(pass);
        System.out.println(pass);
        System.out.println(pass.length());
        String psw = "c012032ddcee83f8969683f98be51ea6ff55e70dd5320a8a0aeef4a203a36c65";
        String result = testDigest(usercodeString + pass + psw);
        System.out.println(result);
        System.out
                .println(testDigest("A672353r1.0cp1319595089906R11102610113010020004015123456789012345http://localhost:8088/ofrcvcardnotify.do2001数据接收成功,验证卡密�?0111026101130"));
    }
}
